<template>
  <MenuPage
    :data="resData.list"
    :columns="columns"
    :page.sync="queryParams.pageIndex"
    :size.sync="queryParams.pageSize"
    :total="resData.total"
    :loading="resData.loading"
    @queryFun="getVerifyProjectList">
    <template slot="search">
      <Button ghost style="height: 32px;" type="primary" class="md-add-jh" @click="showModal()">创建漏洞验证环境</Button>
      <Input
        clearable
        v-model.trim="queryParams.projectName"
        placeholder="验证工程名称"
        @on-change="debounceFn"
        style="width: 180px;margin-left: 15px;" />
      <Button
        type="primary"
        ghost
        style="height: 32px;margin-left: 9px;"
        @click="refreshQueryParams()">
        <i class="el-icon-refresh-right" />
      </Button>
      <Modal
            v-model="modalData.show"
            :title="`${isAdd ? '创建' : '修改'}验证工程`"
            @on-visible-change="changeVisible"
            class="my-modal">
            <Form
                ref="formInline"
                :label-width="110"
                :model="formInline"
                :rules="ruleInline">
                <FormItem prop="projectName" label="验证工程名称">
                    <Input clearable v-model="formInline.projectName" :disabled="!isAdd"></Input>
                </FormItem>
                <FormItem prop="vulnerabilityIds"  label="漏洞" class="my-form-item">
                    <public-vulnerability-select-drawer
                        v-model="formInline.vulnerabilityIds"
                        ref="publicVulnerabilitySelectDrawer"
                        @input="validateVulnerabilityIds"
                        :inner="true"></public-vulnerability-select-drawer>
                </FormItem>
                <FormItem prop="projectTemplateId" label="验证环境模板">
                    <Select filterable transfer filterable clearable v-model="formInline.projectTemplateId" @on-change="chanegTemplate" placeholder="" :disabled="!isAdd">
                        <Option v-for="item in templateList" :value="item.id" :key="item.id" :title="item.name">{{ item.name }}</Option>
                    </Select>
                </FormItem>
                <FormItem prop="description"  label="描述">
                    <Input clearable v-model="formInline.description" type="textarea" :rows="3"></Input>
                </FormItem>
            </Form>
            <div slot="footer" class="footer">
                <Button @click="modalData.show = false">取消</Button>
                <Button @click="saveProject" :loading="modalData.loading" type="primary">确定</Button>
            </div>
        </Modal>
        <Modal
            v-model="templateModalData.show"
            title="保存为模板"
            @on-visible-change="changeTemplateVisible"
            class="my-modal">
            <Alert type="warning" show-icon>本操作需同步生成拓扑缩略图，请耐心等待...</Alert>
            <Form
                ref="templateFormInline"
                :label-width="110"
                :model="templateModalData.formInline"
                :rules="templateModalData.ruleInline">
                <FormItem prop="name" label="模板名称">
                    <Input clearable v-model="templateModalData.formInline.name"></Input>
                </FormItem>
                <FormItem prop="vulnerabilityList" label="漏洞列表">
                    <Input clearable v-model="templateModalData.formInline.vulnerabilityList" type="textarea" :rows="3" disabled></Input>
                </FormItem>
                <FormItem prop="description"  label="描述">
                    <Input clearable v-model="templateModalData.formInline.description" type="textarea" :rows="3"></Input>
                </FormItem>
            </Form>
            <div slot="footer" class="footer">
                <Button @click="templateModalData.show = false">取消</Button>
                <Button @click="saveProjectTemplate" :loading="templateModalData.loading" type="primary">确定</Button>
            </div>
        </Modal>
        <create-template-image
            v-if="showCreate"
            @upload-image-succes="uploadImageSucces"
            @upload-image-error="uploadImageError"
            :projectId="currentProjectId"></create-template-image>
    </template>
  </MenuPage>
</template>
<script>
import CreateTemplateImage from '@/view/testPlatform/components/create-template-image'
import {
    getVerifyProjectList,
    addVerifyProject,
    deleteVerifyProject,
    updateVerifyProject,
    getVulnerabilityVerifyProjectList
} from '@/view/testPlatform/vulnerability/api/vulnerabilityVerifyProject'
import {
    getVerifyProjectTemplateList,
    saveVerifyProjectTemplate,
    getTemplateVulnerability
} from '@/view/testPlatform/vulnerability/api/vulnerabilityVerifyTemplate'
import {
  creatProject
} from '@/view/testPlatform/vulnerability/api/topo'
import { debounce } from '@/libs/utils'
import { validateName } from '@/libs/reg'
import { projectStatusEscape } from '@/view/testPlatform/vulnerability/logic/vulnerabilityLogic'
import PublicVulnerabilitySelectDrawer from '@/view/testPlatform/components/public-vulnerability-select-drawer'

export default {
  name: 'VulnerabilityValidate',
  components: {
    CreateTemplateImage,
    PublicVulnerabilitySelectDrawer
  },
  data () {
    return {
      modalData: {
          show: false,
          loading: false
      },
      templateModalData: {
          show: false,
          loading: false,
          formInline: {
              name: '',
              description: '',
              vulnerabilityList: '',
              picUrl: ''
          },
          ruleInline: {
              name: [
                  { required: true, message: '模板名称不能为空', trigger: 'blur,change' },
                  { type:'string', max: 64, message:'最多输入64个字符', trigger: 'blur,change' },
                  { validator: validateName, trigger: 'blur,change' }
              ],
              description: [
                  { type:'string', max: 200, message:'最多输入200个字符', trigger: 'blur,change' },
              ]
          },
      },
      templateList: [],
      formInline: {
          projectName: '',
          projectTemplateId: '',
          description: '',
          vulnerabilityIds: []
      },
      ruleInline: {
          projectName: [
              { required: true, message: '验证工程名称不能为空', trigger: 'blur,change' },
              { type:'string', max: 64, message:'最多输入64个字符', trigger: 'blur,change' },
              { validator: validateName, trigger: 'blur,change' }
          ],
          vulnerabilityIds: [
              { required: true, type: 'array', message: '漏洞不能为空', trigger: 'blur,change' }
          ],
          description: [
              { type:'string', max: 200, message:'最多输入200个字符', trigger: 'blur,change' },
          ]
      },
      isAdd: false,
      resData: {
          total: 0,
          list: [],
          loading: true
      },
      queryParams: {
          pageIndex: 1,
          pageSize: 10,
          projectName: '',
      },
      columns: [
        {
          title: '验证工程名称',
          key: 'projectName',
          tooltip: true,
        },
        {
          title:'部署状态',
          key:'status',
          render:(h,params)=>{
            let ret = projectStatusEscape(params.row.status)
            return h('Tag', {
              props: {
                color: ret.color
              },
              style: {
                width: '100px',
                'text-align': 'center'
              }
            }, ret.text)
          }
        },
        {
          title: '漏洞',
          key: 'vulnerabilityNames',
          tooltip: true,
        },
        {
          title: '验证环境模板',
          key: 'templateName',
          tooltip: true,
        },
        {
          title: '创建人',
          key: 'creatorName',
          tooltip: true,
        },
        {
          title: '创建时间',
          key: 'created',
          tooltip: true,
        },
        {
          title: '描述',
          key: 'description',
          tooltip: true,
        },
        {
          title: '操作',
          width: 270,
          slot: 'action',
          opList: [
            {

              txt: '验证',
              on:{
                click:(data) => {
                  this.showVerificationPage(data)
                }
              },
              disabled: (data)=>data.status !== 3
            },
            {
              txt: '验证环境',
              on:{
                click:(data) => {
                  this.toTopoPage(data.projectId)
                }
              },
            },
            {
              txt: '保存为模板',
              on:{
                click:(data) => {
                  this.templateModalData.show = true
                  // 获取关联的漏洞列表
                  this.getAllVulnerabilityList(data.projectId)
                  this.currentProjectId = data.projectId
                }
              },
            },
            {
              txt: '修改',
              on:{
                click:(data) => {
                  this.showModal(data)
                }
              },
            },
            {
              txt: '删除',
              tooltip: true,
              type: 'delete',
              title: '确定要删除吗？',
              on:{
                click:(data,e) => {
                  this.deleteItem([data.id])
                }
              },
              disabled: (data)=>data.isUsed
            }
          ]
        }
      ],
      showCreate: false
    }
  },
  mounted () {
    let getPage = this.$route.query.page ? parseInt(this.$route.query.page) : 1
    this.queryParams.pageIndex = getPage
    this.getVerifyProjectList()
  },
  methods:{
        // 漏洞修改后，需要验证
        validateVulnerabilityIds() {
            this.$nextTick(() => {
                this.$refs.formInline.validateField('vulnerabilityIds')
            })
        },
        // 替换验证环境模板后，需要查询关联的漏洞，并将数据在漏洞一栏回显
        async chanegTemplate(id) {
            let associationVulnerabilityList = []
            if (id) {
                associationVulnerabilityList = await this.getTemplateVulnerability(id)
            }
            let associationVulnerabilityIds = []
            associationVulnerabilityList.forEach(item => {
                if (item.vulnerabilityId) { // 有些老数据，模版没有关联漏洞，这些数据要忽略掉
                    associationVulnerabilityIds.push(item.vulnerabilityId)
                }
            })
            if (associationVulnerabilityIds.length) {
                this.$refs.publicVulnerabilitySelectDrawer.getCheckList(associationVulnerabilityIds.join(','))
            }
        },
        // 获取模版关联的漏洞
        getTemplateVulnerability(id) {
            return new Promise((resolve) => {
                getTemplateVulnerability({
                    pageIndex: 1,
                    pageSize: 2147483646,
                    projectTemplateId: id
                }).then(({ code, message, data = {} }) => {
                    if (code !== 1) {
                        resolve([])
                        this.$Message.warning(message)
                        return
                    }
                    resolve(data.items || [])
                }).catch(() => {
                    resolve([])
                    this.$Message.error('获取模版关联的漏洞异常')
                })
            })
        },
        // 获取所有已配置的漏洞
        getAllVulnerabilityList(projectId) {
            getVulnerabilityVerifyProjectList({
                pageIndex: 1,
                pageSize: 2147483646,
                projectId
            }).then(({ code, message, data }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                let list = data.items || []
                let str = ''
                list.forEach(item => {
                    str += `${(item.vulnerabilityName === null || item.vulnerabilityName === undefined) ? '' : item.vulnerabilityName}
`// 用模板字符串拼接换行，特意这么写的，不然会有空格
                })
                this.templateModalData.formInline.vulnerabilityList = str
            }).catch(() => {
                this.$Message.error('获取关联漏洞列表异常')
            })
        },
        // 跳转至topo页面
        toTopoPage(projectId) {
            window.openTrain(`/jjzzTopo/index.html#/ProjectViews?projectId=${projectId}`);
        },
        // 展示验证页面
        showVerificationPage(obj) {
            window.openTrain(`./#/verificationPage?id=${obj.id}&projectId=${obj.projectId}`);
        },
        // 删除工程
        deleteItem(ids) {
            deleteVerifyProject(ids).then(({ code, message }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.$Message.success(`删除验证工程成功`)
                // 删除后展示当前页，当前页没有数据展示前一页
                this.queryParams.pageIndex = (this.resData.list.length == ids.length && this.queryParams.pageIndex > 1) ?
                                this.queryParams.pageIndex - 1 : this.queryParams.pageIndex;
                this.getVerifyProjectList()
            }).catch(() => {
                this.$Message.error(`删除验证工程异常`)
            })
        },
        // 获取可用的模板列表
        getAllTemplateList() {
            getVerifyProjectTemplateList({
                pageIndex: 1,
                pageSize: 2147483646,
            }).then(({ code, message, data = {} }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.templateList = data.items
            }).catch(() => {
                this.$Message.error('获取漏洞验证工程列表异常')
            })
        },
        // 打开模态框
        async showModal(data) {
            this.isAdd = !data
            this.modalData.show = true
            let obj = data || {}
            let vulnerabilityIds = obj.vulnerabilityIds || ''
            this.formInline = Object.assign({}, obj)
            this.$refs.publicVulnerabilitySelectDrawer.getCheckList(vulnerabilityIds)
            this.getAllTemplateList()
        },
        // 拓扑图图片生成并上传生成，拿到数据进行处理
        uploadImageSucces(obj) {
            this.templateModalData.formInline.picUrl = obj.imagePath
            this.saveFn(true)
        },
        // 生成拓扑缩略图失败，
        uploadImageError() {
            this.templateModalData.formInline.picUrl = ''
            this.saveFn(false)
        },
        // 保存方法
        saveFn(type) {
            let data = Object.assign({}, this.templateModalData.formInline)
            delete data.vulnerabilityList
            // 将工程保存为模板
            saveVerifyProjectTemplate(this.currentProjectId, data).then(({ code, message }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.$Message.success(`保存模板成功${type ? '' : '，但生成拓扑图失败，本次模版保存无法查看缩略图'}`)
                this.templateModalData.show = false
            }).catch(() => {
                this.$Message.error('保存模板异常')
            }).finally(() => {
                this.templateModalData.loading = false
            })
        },
        // 将工程模板为模板
        saveProjectTemplate() {
            this.$refs.templateFormInline.validate(valid => {
                if (valid) {
                    this.showCreate = true
                    this.templateModalData.loading = true
                }
            })
        },
        // 保存/修改验证工程
        saveProject() {
            this.$refs.formInline.validate(async valid => {
                if (valid) {
                    this.modalData.loading = true
                    let code = await this.creatProject(this.formInline.projectTemplateId)
                    if (code === 0) {
                        this.modalData.loading = false
                        return
                    }
                    let apiName = this.isAdd ? addVerifyProject : updateVerifyProject
                    // code不是错误码时，携带的是工程详情
                    let data = Object.assign({ projectId: code.id }, this.formInline)
                    if (this.isAdd) { // 创建操作确认把id删掉，避免造成错误
                        delete data.id
                    }
                    apiName(data).then(({ code, message }) => {
                        if (code !== 1) {
                            this.$Message.warning(message)
                            return
                        }
                        // 创建成功
                        this.$Message.success(`${this.isAdd ? '创建' : '修改'}验证工程成功`)
                        this.refreshQueryParams()
                        this.modalData.show = false
                    }).catch(() => {
                        this.$Message.error(`${this.isAdd ? '创建' : '修改'}验证工程异常`)
                    }).finally(() => {
                        this.modalData.loading = false
                    })
                }
            })
        },
        // 创建工程
        creatProject(tmplId) {
            return new Promise((resolve) => {
                creatProject(tmplId ? tmplId : '', {
                    mode: "complete",
                    name: this.formInline.projectName,
                    quotaTypeId: "2", // 配额，2：小型 3：中型 4：大型 5：超大型
                    trainId: 0,
                    type: "normal",
                }, 'complete').then(({ code, message, attribute = {} }) => {
                    if(![1, 2].includes(code)){ // 成功或导入中均不需要报错
                        this.$Message.warning(message)
                        resolve(0)
                        return
                    }
                    resolve(attribute.result)
                }).catch(() => {
                    this.$Message.error('创建拓扑图异常')
                    resolve(0)
                })
            })
        },
        // 隐藏模态框时，重置表单数据
        changeVisible(type) {
            if (!type) {
                this.$refs.formInline.resetFields()
                this.$refs.publicVulnerabilitySelectDrawer.clear()
                this.modalData.loading = false
            }
        },
        changeTemplateVisible(type) {
            if (!type) {
                this.$refs.templateFormInline.resetFields()
                this.templateModalData.loading = false
                this.showCreate = false
            }
        },
        // 重置搜索条件并查询数据
        refreshQueryParams() {
            this.queryParams = {
                pageIndex: 1,
                pageSize: 10,
                projectName: '',
            }
            this.getVerifyProjectList()
        },
        // 防抖方法，用于输入型查询
        debounceFn: debounce(function() {
            this.changePageNow(1);
        }),
        // 查询指定页数据
        changePageNow(val) {
            this.queryParams.pageIndex = val;
            this.getVerifyProjectList();
        },
        // 查询漏洞验证工程列表
        getVerifyProjectList(isRefresh) {
            if (!isRefresh) { // 非定时器触发的刷新列表的操作，需要设置loading状态
                this.resData.loading = true
            }
            getVerifyProjectList(this.queryParams).then(({ code, message, data = {} }) => {
                if (code !== 1) {
                    this.$Message.warning(message)
                    return
                }
                this.resData = {
                    total: data.total || 0,
                    list: data.items || []
                }
            }).catch(() => {
                this.$Message.error('获取漏洞验证工程列表异常')
            }).finally(() => {
                this.resData.loading = false
                clearTimeout(this.timer)
                this.timer = setTimeout(() => {
                    this.getVerifyProjectList(true)
                }, 10000)
            })
        },
    },
    beforeDestroy(){
        clearTimeout(this.timer)
    }
}
</script>
<style scoped>
.item-table {
  display: table;
  width: 100%;
  border: 1px solid #eee;
  table-layout: fixed;
  word-break: break-all;
}
.item-table p {
  display: table-row;
  line-height: 36px;
  text-align: center;
}
.item-table p span {
  display: table-cell;
  border-bottom: 1px solid #eee;
}
.ios-alert {
  /* position: absolute;
        top: -44px;
        right: -404px; */
  color: orange;
  font-size: 16px;
  cursor: pointer;
}
.too {
  position: absolute;
  left: 113px;
  top: -1px;
}
</style>
